//
// https://github.com/ServiceStack/ServiceStack.Redis
// ServiceStack.Redis: ECMA CLI Binding to the Redis key-value storage system
//
// Authors:
//   Demis Bellot (demis.bellot@gmail.com)
//
// Copyright 2013 Service Stack LLC. All Rights Reserved.
//
// Licensed under the same terms of ServiceStack.
//

using System;
using System.Collections.Generic;
using ServiceStack.Caching;

namespace ServiceStack.Redis
{
	/// <summary>
	/// BasicRedisClientManager for ICacheClient
	/// 
	/// For more interoperabilty I'm also implementing the ICacheClient on
	/// this cache client manager which has the affect of calling 
	/// GetCacheClient() for all write operations and GetReadOnlyCacheClient() 
	/// for the read ones.
	/// 
	/// This works well for master-slave replication scenarios where you have 
	/// 1 master that replicates to multiple read slaves.
	/// </summary>
	public partial class BasicRedisClientManager
		: ICacheClient
	{
		public ICacheClient GetCacheClient()
		{
            return new RedisClientManagerCacheClient(this);
        }

		public ICacheClient GetReadOnlyCacheClient()
		{
			return ConfigureRedisClient(this.GetReadOnlyClient());
		}

		private ICacheClient ConfigureRedisClient(IRedisClient client)
		{
			return client;
		}

		#region Implementation of ICacheClient

		public bool Remove(string key)
		{
			using (var client = GetReadOnlyCacheClient())
			{
				return client.Remove(key);
			}
		}

		public void RemoveAll(IEnumerable<string> keys)
		{
			using (var client = GetCacheClient())
			{
				client.RemoveAll(keys);
			}
		}

		public T Get<T>(string key)
		{
			using (var client = GetReadOnlyCacheClient())
			{
				return client.Get<T>(key);
			}
		}

		public long Increment(string key, uint amount)
		{
			using (var client = GetCacheClient())
			{
				return client.Increment(key, amount);
			}
		}

		public long Decrement(string key, uint amount)
		{
			using (var client = GetCacheClient())
			{
				return client.Decrement(key, amount);
			}
		}

		public bool Add<T>(string key, T value)
		{
			using (var client = GetCacheClient())
			{
				return client.Add(key, value);
			}
		}

		public bool Set<T>(string key, T value)
		{
			using (var client = GetCacheClient())
			{
				return client.Set(key, value);
			}
		}

		public bool Replace<T>(string key, T value)
		{
			using (var client = GetCacheClient())
			{
				return client.Replace(key, value);
			}
		}

		public bool Add<T>(string key, T value, DateTime expiresAt)
		{
			using (var client = GetCacheClient())
			{
				return client.Add(key, value, expiresAt);
			}
		}

		public bool Set<T>(string key, T value, DateTime expiresAt)
		{
			using (var client = GetCacheClient())
			{
				return client.Set(key, value, expiresAt);
			}
		}

		public bool Replace<T>(string key, T value, DateTime expiresAt)
		{
			using (var client = GetCacheClient())
			{
				return client.Replace(key, value, expiresAt);
			}
		}

		public bool Add<T>(string key, T value, TimeSpan expiresIn)
		{
			using (var client = GetCacheClient())
			{
				return client.Add(key, value, expiresIn);
			}
		}

		public bool Set<T>(string key, T value, TimeSpan expiresIn)
		{
			using (var client = GetCacheClient())
			{
				return client.Set(key, value, expiresIn);
			}
		}

		public bool Replace<T>(string key, T value, TimeSpan expiresIn)
		{
			using (var client = GetCacheClient())
			{
				return client.Replace(key, value, expiresIn);
			}
		}

		public void FlushAll()
		{
			using (var client = GetCacheClient())
			{
				client.FlushAll();
			}
		}

		public IDictionary<string, T> GetAll<T>(IEnumerable<string> keys)
		{
			using (var client = GetReadOnlyCacheClient())
			{
				return client.GetAll<T>(keys);
			}
		}

		#endregion
	}


}